﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BrainSculptor
{
    public partial class frmShape : Form
    {
        public frmShape(Shapes shape, Color color, DateTime end)
        {
            InitializeComponent();
            this.shape = shape;
            this.color = color;
            sessionEnd = end;
        }


        Shapes shape = Shapes.Triangle;
        Color color = Color.Blue;
        int miliseconds = 0;
        int seconds = 0;
        int counter = 0;
        DateTime startTime;
        DateTime counterTime = DateTime.Now;
        int centerX;
        int centerY;
        int radius;
        int rows;
        int max = 0;
        DateTime sessionEnd;
        int secondsLeft;

        List<int> results = new List<int>();

        public List<int> Results
        {
            get { return results; }
        }

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
                this.Close();

            if (e.KeyCode == Keys.Space)
                TimerAction();
        }

        bool enabled = false;

        private void TimerAction()
        {
            if (!enabled)
            {
                seconds = 0;
                enabled = true;
                startTime = DateTime.Now;
            }
            else
            {
                enabled = false;
                counterTime = DateTime.Now;
                results.Add(seconds);
                Label lbl = new Label();
                lbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
                lbl.ForeColor = Color.White;
                lbl.Location = new Point(((results.Count - 1) / rows) * 80
                    , lblTimer.Top + lblTimer.Height + (((results.Count - 1) % rows) * 20));
                lbl.Text = FormatTime(seconds);
                lbl.AutoSize = true;
                if (seconds > max)
                {
                    max = seconds;
                    if (results.Count > 1)
                        lbl.ForeColor = Color.LimeGreen;
                    if (max > Properties.Settings.Default.Record)
                    {
                        Properties.Settings.Default.Record = max;
                        Properties.Settings.Default.Save();
                        lbl.ForeColor = Color.Red;
                    }
                }
                pnlMain.Controls.Add(lbl);
            }
            pnlCounter.Visible = !enabled;
            //tmrTimer.Enabled = enabled;
        }

        private void pnlMain_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = pnlMain.CreateGraphics();
            DrawShape(g);
        }

        void DrawShape(Graphics g)
        {
            SolidBrush myBrush = new SolidBrush(color);
            SolidBrush backBrush = new SolidBrush(pnlMain.BackColor);

            int corners = 0;
            double start = -Math.PI / 2;
            int radius2;

            switch (shape)
            {
                case Shapes.Circle:
                    g.FillEllipse(myBrush, new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2));
                    break;
                case Shapes.Square:
                    g.FillRectangle(myBrush, new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2));
                    break;
                case Shapes.Triangle:
                    corners = 3;
                    DrawPolygon(g, myBrush, corners);
                    break;
                case Shapes.Diamond:
                    corners = 4;
                    DrawPolygon(g, myBrush, corners);
                    break;
                case Shapes.Pentagon:
                    corners = 5;
                    DrawPolygon(g, myBrush, corners);
                    break;
                case Shapes.Hexagon:
                    corners = 6;
                    DrawPolygon(g, myBrush, corners);
                    break;
                case Shapes.Pentagram:
                    corners = 5;
                    start = -Math.PI / 2;
                    DrawPolygon(g, myBrush, corners, radius, start, 2);
                    start = Math.PI / 2;
                    radius2 = Convert.ToInt32(Math.Floor(radius * Math.Sin(19 * Math.PI / 180) / Math.Sin(54 * Math.PI / 180))) - 1;
                    DrawPolygon(g, myBrush, corners, radius2, start, 1);
                    break;
                case Shapes.Hexagram:
                    corners = 3;
                    DrawPolygon(g, myBrush, corners);
                    start = Math.PI / 2;
                    DrawPolygon(g, myBrush, corners, radius, start, 1);
                    break;
                case Shapes.Ring:
                    g.FillEllipse(myBrush, new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2));
                    radius2 = radius / 2;
                    g.FillEllipse(backBrush, new Rectangle(centerX - radius2, centerY - radius2, radius2 * 2, radius2 * 2));
                    break;
                case Shapes.Frame:
                    g.FillRectangle(myBrush, new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2));
                    radius2 = radius / 2;
                    g.FillRectangle(backBrush, new Rectangle(centerX - radius2, centerY - radius2, radius2 * 2, radius2 * 2));
                    break;
                case Shapes.Cross:
                    radius2 = radius / 3;
                    g.FillRectangle(myBrush, new Rectangle(centerX - radius2, centerY - radius, radius2 * 2, radius * 2));
                    g.FillRectangle(myBrush, new Rectangle(centerX - radius, centerY - radius2, radius * 2, radius2 * 2));
                    break;
                case Shapes.X:
                    corners = 4;
                    radius2 = radius /2 ;//Convert.ToInt32(radius / 2 * Math.Sqrt(2));
                    DrawPolygon(g, myBrush, corners, radius2, start, 1);
                    double angle = 2 * Math.PI / corners;
                    double start2 = Math.PI / 4;
                    int x = 0;
                    int y = 0;
                    for (int i = 0; i < corners; i++)
                    {
                        x = Convert.ToInt32(centerX + Convert.ToInt32(radius2 * Math.Sqrt(2)) * (float)Math.Cos(start2 + angle * i));
                        y = Convert.ToInt32(centerY + Convert.ToInt32(radius2 * Math.Sqrt(2)) * (float)Math.Sin(start2 + angle * i));
                        DrawPolygon(g, myBrush, corners, radius2, start, 1, x, y);
                    }
                    break;
                default:
                    break;
            }
        }

        private void DrawPolygon(Graphics g, SolidBrush myBrush, int corners)
        {
            double start = -Math.PI / 2;
            DrawPolygon(g, myBrush, corners, radius, start, 1);
        }

        private void DrawPolygon(Graphics g, SolidBrush myBrush, int corners, int radius, double start, int multiplier)
        {
            DrawPolygon(g, myBrush, corners, radius, start, multiplier, centerX, centerY);
        }

        private void DrawPolygon(Graphics g, SolidBrush myBrush, int corners, int radius, double start, int multiplier, int centerX, int centerY)
        {
            double angle = 2 * Math.PI / corners;
            PointF[] points = new PointF[corners];
            for (int i = 0; i < corners; i++)
            {
                points[i] = new PointF(centerX + radius * (float)Math.Cos(start + angle * i * multiplier), centerY + radius * (float)Math.Sin(start + angle * i * multiplier));
            }
            g.FillPolygon(myBrush, points);
        }

        private void tmrTimer_Tick(object sender, EventArgs e)
        {
            TimeSpan diff;
            DateTime now = DateTime.Now;
            if (enabled)
            {
                diff = now.Subtract(startTime);
                miliseconds = diff.Milliseconds % 100;
                seconds = diff.Seconds;
                lblTimer.Text = FormatTime(seconds);
                lblMiliSeconds.Text = String.Format("{0:00}", miliseconds % 100);
            }
            else
            {
                diff = now.Subtract(counterTime);
                if (counter != (diff.Seconds + diff.Minutes * 60) % 120)
                {
                    counter = (diff.Seconds + diff.Minutes * 60) % 120;
                    pnlCounter.Refresh();
                }
            }

            if (sessionEnd > DateTime.Now)
            {
                diff = sessionEnd.Subtract(DateTime.Now);
                int s = diff.Seconds % 60 + diff.Minutes * 60 + diff.Hours * 60 * 60;
                if (s != secondsLeft)
                {
                    secondsLeft = s;
                    lblSessionEnd.Text = FormatTime(secondsLeft);
                }
            }

        }

        private string FormatTime(int seconds)
        {
            return String.Format("{0:00}", seconds / (60 * 60)) + ":"
                                + String.Format("{0:00}", seconds % (60 * 60) / 60) + ":"
                                + String.Format("{0:00}", seconds % 60);
        }

        private void frmShape_MouseClick(object sender, MouseEventArgs e)
        {
            TimerAction();
        }

        private void frmShape_Load(object sender, EventArgs e)
        {
            centerX = pnlMain.Width / 2;
            centerY = pnlMain.Height / 2;
            radius = pnlMain.Height / 8;

            pnlCounter.Height = radius / 3;
            pnlCounter.Width = pnlCounter.Height;
            //pnlCounter.Top = centerY + centerY / 2 - pnlCounter.Height / 2;
            pnlCounter.Top = pnlMain.Height - centerY / 3 - pnlCounter.Height / 2;
            pnlCounter.Left = centerX - pnlCounter.Width / 2;

            rows = (pnlMain.Height - lblTimer.Top - lblTimer.Height) / 20;
        }

        private void pnlCounter_Paint(object sender, PaintEventArgs e)
        {
            bool side = counter / 60 != 0;
            int seconds = counter % 60;
            Graphics g = pnlCounter.CreateGraphics();
            SolidBrush myBrush = new SolidBrush(Color.DarkGray);
            if (side)
                g.FillPie(myBrush, new Rectangle(0, 0, pnlCounter.Width, pnlCounter.Height),270 +( seconds * 6), 360 - (seconds * 6));
            else
                g.FillPie(myBrush, new Rectangle(0, 0, pnlCounter.Width, pnlCounter.Height), 270, seconds * 6);
        }

        private void frmShape_ResizeEnd(object sender, EventArgs e)
        {
            //centerX = pnlMain.Width / 2;
            //centerY = pnlMain.Height / 2;
            //radius = pnlMain.Height / 8;

            //pnlCounter.Height = radius / 3;
            //pnlCounter.Width = pnlCounter.Height;
            //pnlCounter.Top = centerY + centerY / 2 - pnlCounter.Height / 2;
            //pnlCounter.Left = centerX - pnlCounter.Width / 2;

            //rows = (pnlMain.Height - lblTimer.Top - lblTimer.Height) / 20;
        }
    }
}
